package com.nuanshui.framework.utils.mongo;
import java.net.UnknownHostException;
import java.util.*;

import com.mongodb.*;
import com.nuanshui.framework.lang.SysStringUtils;
import org.springframework.data.mongodb.MongoDbFactory;


/**
 * Created by superman on 2014/6/30.
 */
 
public class MongoManager {
    private DB db;
    private static final Integer soTimeOut = 300000;
    private static final Integer connectionsPerHost = 500;
    private static final Integer threadsAllowedToBlockForConnectionMultiplier = 500;

    public MongoManager(MongoDbFactory mongoDbFactory)  {
        db=mongoDbFactory.getDb();
    }

    @SuppressWarnings("deprecation")
	public MongoManager(String host, int port, String database, String username, String password)  {
            MongoClient mongoClient;
			try {
                List<MongoCredential> credentialsList=Collections.<MongoCredential>emptyList();
                if(SysStringUtils.isNotEmpty(username) && SysStringUtils.isNotEmpty(password))
                {
                    MongoCredential credential = MongoCredential.createCredential(username, database, password.toCharArray());
                    credentialsList.add(credential);
                }

				mongoClient = new MongoClient(new ServerAddress(host, port),credentialsList,new MongoClientOptions.Builder()
				        .socketTimeout(soTimeOut)
				        .connectionsPerHost(connectionsPerHost)
				        .threadsAllowedToBlockForConnectionMultiplier(threadsAllowedToBlockForConnectionMultiplier)
				        .socketKeepAlive(true)
				        .build()
				);
				db = mongoClient.getDB(database);

			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    }
 
    public void save(String collection, DBObject dbObject) {
        db.getCollection(collection).save(dbObject);
    }
 
    public void delete(String collection, DBObject query) {
        db.getCollection(collection).remove(query);
    }
 
    // 此处不使用toArray()方法直接转换为List,是因为toArray()会把结果集直接存放在内存中，
    // 如果查询的结果集很大，并且在查询过程中某一条记录被修改了，就不能够反应到结果集中，从而造成"不可重复读"
    // 而游标是惰性获取数据
    public List<DBObject> find(String collection, DBObject query, DBObject fields, int limit) {
        List<DBObject> list = new LinkedList<DBObject>();
        Cursor cursor = db.getCollection(collection).find(query, fields).limit(limit);
        while (cursor.hasNext()) {
            list.add(cursor.next());
        }
        return list.size() > 0 ? list : null;
    }
 
    public List<DBObject> find(String collection, DBObject query, DBObject fields, DBObject orderBy, int pageNum, int pageSize) {
        List<DBObject> list = new ArrayList<DBObject>();
        Cursor cursor = db.getCollection(collection).find(query, fields).skip((pageNum - 1) * pageSize).limit(pageSize).sort(orderBy);
        while (cursor.hasNext()) {
            list.add(cursor.next());
        }
        return list.size() > 0 ? list : null;
    }
 
    public DBObject findOne(String collection, DBObject query, DBObject fields) {
        return db.getCollection(collection).findOne(query, fields);
    }
 
    public void update(String collection, DBObject query, DBObject update, boolean upsert, boolean multi) {
        db.getCollection(collection).update(query, update, upsert, multi);
    }
 
    public long count(String collection, DBObject query) {
        return db.getCollection(collection).count(query);
    }
 
 
    //查询出key字段,去除重复，返回值是{_id:value}形式的list
    @SuppressWarnings("rawtypes")
	public List distinct(String collection, String key, DBObject query) {
        return db.getCollection(collection).distinct(key, query);
    }
 
    public DB getDB() {
    	return this.db;
    } 
    
    public static void main(String[] args) {
		MongoManager mongoManager = new MongoManager("10.0.0.254",27017, "statistics","sa","123");
		new HashMap<String, Object>();
		/*//List<TestUser> testUsers = mongoManager.find("test", map,null,null,2,2,TestUser.class);
	    MongoQuery mongoQuery = new MongoQuery();
	    mongoQuery.setCollection("shareClick");
	    mongoQuery.setNumPerPage(40);
	    mongoQuery.setPageNum(1);
	    //mongoQuery.addQueryParam("name", "dddd");
	    mongoQuery.addSortField("name", MongoQuery.ORDER_DIRECTION_DESC);
		List<TestShareClick> testUsers = mongoManager.find(mongoQuery,TestShareClick.class);
		for(TestShareClick testUser :testUsers) {
	    	System.out.println(testUser.getNick()+"  "+testUser.getUserId());
	    }*/
		BasicDBObject basicDBObject = new BasicDBObject();
		basicDBObject.append("create_time",new Date());
		mongoManager.save("test2", basicDBObject);
    }
 
}